<?php
namespace Dershun\RealNameAuthentication;

/**
* 加密相关类
*/
class Encryption
{
	protected $config;//配置数据
	protected $crypted;//加密后的报文数据
	protected $msectime;//时间戳（毫秒）
	protected $Sign;//签名
	protected $errorMsg;//配置错误信息说明
	private $error;//错误信息

	protected function __construct()
	{
		$config = require_once(dirname(__FILE__)."/config.php");

		if(empty($config['interface'])) {
			$this->setError(100,"缺少配置数据");
			return false;
		}else if(empty($config['interface']['appId'])){
			$this->setError(100,"缺少appId");
			return false;
		}else if(empty($config['interface']['secretKey'])){
			$this->setError(100,"缺少secretKey");
			return false;
		}else if(empty($config['interface']['bizId'])){
			$this->setError(100,"缺少bizId");
			return false;
		}

		$this->config   = $config['interface'];
		$this->errorMsg = $config['errorMsg'];
	}

	/**
	 * 加密报文数据
	 * @param  [type] $data 需要加密的数据
	 * @return [type]       [description]
	 */
	protected function encryptedMessage($data){

		if(empty($data)) {
			$this->setError(101,"缺少报文数据");
			return false;
		}

		$message = is_array($data)?json_encode($data):$data;

		if(empty($message)) {
			$this->setError(102,"报文数据错误");
			return false;
		}

        $key = hex2bin($this->config['secretKey']);
        $cipher = "aes-128-gcm";
        $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher));
        $tag = null;
        $encrypt = openssl_encrypt($message, $cipher, $key, OPENSSL_RAW_DATA,$iv,$tag);
        $this->crypted = base64_encode(($iv.$encrypt.$tag));
        return $this->crypted;
	}

	/**
	 * 获取签名
	 * @return [type] [description]
	 */
	protected function getSign($getdata = []){
		list($t1, $t2) = explode(' ', microtime());
        $this->msectime = (string)sprintf('%.0f',(floatval($t1)+floatval($t2))*1000);
        
        $data = [
            "appId"=>$this->config['appId'],
            "bizId"=>$this->config['bizId'],
            "timestamps"=>$this->msectime,
        ];
        
        if(!empty($getdata)){
            $data = $data+$getdata;
        }
        ksort($data);
        $signdata = "";
        foreach ($data as $key => $value) {
        	$signdata .= $key.$value;
        }
        
		if(empty($this->crypted)) {
			$this->setError(103,"缺少加密报文数据");
			return false;
		}

	    $waitfor = $this->config['secretKey'].$signdata;

	    if(empty($getdata)){
	    	$waitfor .= json_encode(["data"=>$this->crypted]);
	    }

		$this->Sign = hash("sha256",$waitfor);//进行SHA256计算

		return $this->Sign;
	}

	/**
	 * 设置错误信息
	 * @param [type] $code    [description]
	 * @param [type] $message [description]
	 */
	protected function setError($code,$message){
		$this->error = [
			"code" => $code,
			"message" => $message
		];
	}

	/**
	 * 获取错误信息
	 * @param [type] $code    [description]
	 * @param [type] $message [description]
	 */
	public function getError(){
		return $this->error;
	}

}